本篇文章會介紹 auth 的部分會做的設定,在這裡我們會執行帳戶註冊、驗證的工作,其中註冊時會生成一個 JWT 當做這個帳戶的金鑰,使用者就必須輸入這個金鑰進行身分驗證,當驗證成功才可以執行後續的指令
auth 的架構很單純,先像下面的圖片一樣建立好各個 class
@RestController
@RequestMapping("api/auth")
@RequiredArgsConstructor
public class AuthenticationController {
private final AuthenticationService service;
// 註冊
@PostMapping("/register")
public ResponseEntity<AuthenticationResponse> register(
@RequestBody RegisterRequest request
){
return ResponseEntity.ok(service.register(request));
}
//登入
@PostMapping("/authentication")
public ResponseEntity<AuthenticationResponse> authenticate(
@RequestBody AuthenticationRequest request
){
return ResponseEntity.ok(service.authenticate(request));
}
}
Service中,註冊功能我們建立了資料表的資料,其中的 role,會在指定身分權限能做的事時派上用場
登入的部分用到了Spring Security本身提供的驗證方式,當驗證失敗時會報錯,我們可以在這邊用一個全域的處理錯誤的 class 來接收到這個錯誤,並且將錯誤訊息先自己處理後再回傳給用戶看
JwtService 是自己撰寫的跟 JWT 相關的服務,在這裡我們主要的功能是要生成 JWT,我們會將本次的使用者的相關資料進行加密,並使用相關的套件將使用者資料編碼成 JWT
@Service
@RequiredArgsConstructor
public class AuthenticationService {
private final UserRepository repository;
// 密碼加密
private final PasswordEncoder passwordEncoder;
// 生成 JWT
private final JwtService jwtService;
private final AuthenticationManager authenticationManager;
public AuthenticationResponse register(RegisterRequest request) {
//建立一個User,輸入傳入的資料,包括:name、email、password、權限
var user = User.builder()
.firstname(request.getFirstname())
.lastname(request.getLastname())
.email(request.getEmail())
.password(passwordEncoder.encode(request.getPassword()))
.role(request.getRole())
.build();
repository.save(user);
var jwtToken = jwtService.generateToken(user);
return AuthenticationResponse.builder()
.token(jwtToken)
.build();
}
public AuthenticationResponse authenticate(AuthenticationRequest request) {
// Spring Security 提供的身分驗證的方法
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
request.getEmail(),
request.getPassword()
)
);
var user = repository.findByEmail(request.getEmail())
.orElseThrow();
var jwtToken = jwtService.generateToken(user);
return AuthenticationResponse.builder()
.token(jwtToken)
.build();
}
}
這個是註冊時用到的 Request
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class RegisterRequest {
//設定註冊所需要的參數
private String firstname;
private String lastname;
private String email;
private String password;
private Role role;
}
這個是登入時用到的 Request
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationRequest {
private String email;
String password;
}
這個是我們用來回傳 token時用到的 Response
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class AuthenticationResponse {
private String token;
}
本篇文章簡單的說明註冊及登入會執行的任務,下篇文章會介紹一些額外設置,例如 : 怎麼建立全域的例外處理將報錯的訊息整理給用戶看